package com.grupobbva.seguridad.web.servlet.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.grupobbva.seguridad.domain.Aplicacion;
import com.grupobbva.seguridad.domain.Control;
import com.grupobbva.seguridad.domain.Opcion;
import com.grupobbva.seguridad.domain.OpcionPK;
import com.grupobbva.seguridad.domain.Perfil;
import com.grupobbva.seguridad.domain.Perfil;
import com.grupobbva.seguridad.domain.PerfilControl;
import com.grupobbva.seguridad.domain.PerfilControlPK;
import com.grupobbva.seguridad.domain.PerfilOpcion;
import com.grupobbva.seguridad.domain.PerfilOpcionPK;
import com.grupobbva.seguridad.domain.PerfilPK;
import com.grupobbva.seguridad.domain.TablaDetalle;
import com.grupobbva.seguridad.service.AdministracionService;
import com.grupobbva.seguridad.service.SeguridadService;
import com.grupobbva.seguridad.util.Constante;
import com.grupobbva.seguridad.util.ResultadoOperacion;
import com.grupobbva.seguridad.util.ResultadoOperacionExito;
import com.grupobbva.seguridad.util.Util;

@Controller
public class MantenimientoPerfilController extends BaseController {

	@Autowired
	private AdministracionService administracionService;
	
	@Autowired
	private SeguridadService seguridadService;

	@RequestMapping("/permnt.do")
    public String mostrar(HttpServletRequest request) throws Exception {
		request.setAttribute("aplicacion", seguridadService.obtenerAplicacion(getParameterLong(request, "aplicacionId")));
		request.setAttribute("estados", administracionService.obtenerDetalles(Constante.TG_ESTADOS_REGISTRO));
		request.setAttribute("tipos", administracionService.obtenerDetalles(Constante.TG_TIPOS_PERFIL));
    	return getRelativeURL("permnt");
    }
	
	@RequestMapping("/perlst.do")
    public String listar(HttpServletRequest request) throws Exception {
		Perfil perfil = new Perfil(new PerfilPK(getParameterLong(request, "filtroAplicacionId"), getParameterLong(request, "filtroCodigo")));
		perfil.setNombreCorto(getParameterString(request, "filtroNombreCorto"));
		perfil.setNombreLargo(getParameterString(request, "filtroNombreLargo"));
		perfil.setEstado(new TablaDetalle(getParameterLong(request, "filtroEstadoId")));
		
		request.setAttribute("perfiles", seguridadService.obtenerPerfiles(perfil));
		
    	return getRelativeURL("perlst");
    }
	
	@RequestMapping("/perupd.do")
    public String modificar(HttpServletRequest request) throws Exception {
		Perfil perfil = null;
		if (getParameterLong(request, "perfilId") == null) {
			perfil = new Perfil(new PerfilPK(getParameterLong(request, "aplicacionId"), null));
			perfil.setTipo(new TablaDetalle());
			perfil.setEstado(new TablaDetalle());
		} else {
			perfil = seguridadService.obtenerPerfil(new PerfilPK(getParameterLong(request, "aplicacionId"), getParameterLong(request, "perfilId")));
		}
		request.setAttribute("perfil",  perfil);
		request.setAttribute("estados", administracionService.obtenerDetalles(Constante.TG_ESTADOS_REGISTRO));
		request.setAttribute("tipos", administracionService.obtenerDetalles(Constante.TG_TIPOS_PERFIL));
    	return getRelativeURL("perreg");
    }
	
	@RequestMapping("/perdel.do")
    public String eliminar(HttpServletRequest request) throws Exception {
    	ResultadoOperacion resultado = null;
		try {
			String codigoMensaje  = "perfil.eliminar.exito";
						
			seguridadService.eliminarPerfil(new Perfil(new PerfilPK(getParameterLong(request, "aplicacionId"), getParameterLong(request, "perfilId"))));
			
			resultado = new ResultadoOperacionExito(Util.getMessage(codigoMensaje));
		} catch (Exception e) {
			resultado = guardarMensajeError(request, e);
		}
    	return getRelativeAjaxURL(request, resultado);
    }
	
	@RequestMapping("/perreg.do")
    public String grabar(@ModelAttribute("perfil") Perfil perfil, HttpServletRequest request) throws Exception {
		ResultadoOperacion resultado = null;
		try {
			String codigoMensaje  = null;
			if ("copiar".equals(request.getParameter("operacion"))) {
				codigoMensaje  = "perfil.copiar.exito";
				seguridadService.copiarPerfil(perfil, getUsuario(request));
			} else {
				codigoMensaje  = "perfil."+((perfil.getId().getPerfilId()==null)?"registrar":"modificar")+".exito";
				seguridadService.registrarPerfil(perfil, getUsuario(request));
			}
			resultado = new ResultadoOperacionExito(Util.getMessage(codigoMensaje));
		} catch (Exception e) {
			resultado = guardarMensajeError(request, e);
		}
    	return getRelativeAjaxURL(request, resultado);
    }
	@RequestMapping("/peropcupd.do")
    public String mostrarAsignacion(HttpServletRequest request) throws Exception {
		PerfilPK perfilPK = new PerfilPK(getParameterLong(request, "aplicacionId"), getParameterLong(request, "perfilId"));
		Perfil perfil = seguridadService.obtenerPerfil(perfilPK);
		request.setAttribute("perfil", perfil);
		request.setAttribute("tipoConsulta", (Constante.TD_PERFIL_CONSULTA == perfil.getTipo().getDetalleId().longValue()));
		
		List<Opcion> opciones   = seguridadService.obtenerPerfilAplicacionOpcionesSeleccion(perfilPK);
		List<Control> controles = seguridadService.obtenerPerfilAplicacionControlesSeleccion(perfilPK);
		
		List<Map> lista = new ArrayList<Map>();
		
		for (Opcion opcion : opciones) {
			Map registro = new HashMap();
			registro.put("codigoInterno", opcion.getId().getOpcionId());
			registro.put("codigo", opcion.getId().getOpcionId());
			registro.put("nombre", opcion.getNombreLargoJerarquico());
			registro.put("tipo"  , opcion.getTipo().getNombreLargo());
			registro.put("tipoId", opcion.getTipo().getDetalleId());
			registro.put("visible", opcion.getSeleccion());
			registro.put("leer", opcion.getLeer());
			registro.put("crear", opcion.getCrear());
			registro.put("eliminar", opcion.getEliminar());			
			registro.put("arbol" , opcion.getArbol());
			lista.add(registro);
			for (Control control : controles) {
				//System.out.println(opcion.getId().getOpcionId() + " = " + control.getId().getOpcionId());
				if(opcion.getId().getOpcionId().equals(control.getId().getOpcionId())) {
					registro = new HashMap();
					registro.put("codigoInterno", control.getId().getOpcionId()+"-"+control.getId().getControlId());
					registro.put("codigo", control.getId().getOpcionId()+"."+control.getId().getControlId());
					registro.put("nombre", Util.generarSangriaJerarquica(opcion.getNivel()+1) + control.getNombre());
					registro.put("tipo"  , control.getTipo().getNombreLargo());
					registro.put("tipoId", control.getTipo().getDetalleId());
					registro.put("visible", control.getSeleccion());
					registro.put("editable", control.getEditable());
					registro.put("arbol" , opcion.getArbol());
					lista.add(registro);
				}
			}
		}
		
		request.setAttribute("opciones", lista);
		
    	return getRelativeURL("peropc");
    }
	@RequestMapping("/peropcreg.do")
    public String grabarAsignacion(@ModelAttribute("perfil") Perfil perfil, HttpServletRequest request) throws Exception {
		ResultadoOperacion resultado = null;
		try {
			String codigoMensaje  = "perfil.opciones.registrar.exito";
			
			String[] opcionesId = request.getParameterValues("opcionId");
			String[] leerIds = request.getParameterValues("leerId");
			String[] eliminarIds = request.getParameterValues("eliminarId");
			String[] crearIds = request.getParameterValues("crearId");
			

			if (opcionesId != null) {
				List<PerfilOpcion>  opciones  = new ArrayList<PerfilOpcion>();
				List<PerfilControl> controles = new ArrayList<PerfilControl>();
				for (int i = 0; i < opcionesId.length; i++) {
					String[] ids = opcionesId[i].split("-");
					if (ids.length == 1) {
						PerfilOpcion perfilOpc = new PerfilOpcion(new PerfilOpcionPK(perfil.getId().getAplicacionId(), perfil.getId().getPerfilId(), Long.parseLong(opcionesId[i])));
						if(leerIds != null){
							for(int j = 0; j < leerIds.length; j++){
								String[] leerId = leerIds[j ].split("-");
								if(ids[0].toString().equals(leerId[0].toString())){
									perfilOpc.setCodigoLeer(Constante.TD_OPCION_LECTURA);
									break;
								}
							}
						}
						if(perfilOpc.getCodigoLeer()==null)
							perfilOpc.setCodigoLeer(Constante.TD_OPCION_DEFAULT);
						
						if(crearIds != null){
							for(int k = 0; k < crearIds.length; k++){
								String[] crearId = crearIds[k].split("-");
								if(ids[0].toString().equals(crearId[0].toString())){
									perfilOpc.setCodigoCrear(Constante.TD_OPCION_CREAR);
									break;
								}
							}
						}
						if(perfilOpc.getCodigoCrear()==null)
							perfilOpc.setCodigoCrear(Constante.TD_OPCION_DEFAULT);
						
						if(eliminarIds != null){
							for(int l = 0; l < eliminarIds.length; l++){
								String[] eliminarId = eliminarIds[l].split("-");
								if(ids[0].toString().equals(eliminarId[0].toString())){
									perfilOpc.setCodigoEliminar(Constante.TD_OPCION_ELIMINAR);
									break;
								}
							}
						}
						if(perfilOpc.getCodigoEliminar()==null)
							perfilOpc.setCodigoEliminar(Constante.TD_OPCION_DEFAULT);
						
						opciones.add(perfilOpc);
						
//						opciones.add(new PerfilOpcion(new PerfilOpcionPK(
//								perfil.getId().getAplicacionId(), perfil.getId().getPerfilId(), Long.parseLong(opcionesId[i]))));
					} else {
						PerfilControl perfilControl = new PerfilControl(new PerfilControlPK(
								perfil.getId().getAplicacionId(), perfil.getId().getPerfilId(), Long.parseLong(ids[0]), Long.parseLong(ids[1])));
						perfilControl.setEditable((request.getParameter("editableId"+opcionesId[i])!=null));
						controles.add(perfilControl);
					}
				}
				perfil.setPerfilOpcions(opciones);
				perfil.setPerfilControls(controles);
			}
			
			seguridadService.registrarPerfilOpciones(perfil,getUsuario(request));
			
			resultado = new ResultadoOperacionExito(Util.getMessage(codigoMensaje));
		} catch (Exception e) {
			resultado = guardarMensajeError(request, e);
		}
		return getRelativeAjaxURL(request, resultado);
    }
}
